import Foundation

// 父类：遵循Codable
class Person: Codable {
    var name: String = ""
    let age: Int
    let email: String?  // 可选属性
    
    init(name: String, age: Int, email: String?) {
        self.name = name
        self.age = age
        self.email = email
    }
    
    // 父类的CodingKeys（仅包含自身属性）
    enum CodingKeys: String, CodingKey {
        case name, age, email
    }
}

// 子类：继承自Person，需手动实现Codable
class Student: Person {
    var school: String = ""
    var school1: String = "456"
    let grade: Int?     // 可选属性
    
    init(name: String, age: Int, email: String?, grade: Int?) {
        self.grade = grade
        super.init(name: name, age: age, email: email)
    }
    
    // 子类的CodingKeys（仅包含自身属性）
    enum CodingKeys: String, CodingKey {
        case school1, grade
    }
    
    // 解码逻辑：先解析子类属性，再解析父类属性
    required init(from decoder: Decoder) throws {
        // 1. 解析子类自己的属性
        let subclassContainer = try decoder.container(keyedBy: CodingKeys.self)
        self.school = try subclassContainer.decodeIfPresent(String.self, forKey: .school1) ?? "abc"
        self.grade = try subclassContainer.decodeIfPresent(Int.self, forKey: .grade)  // 可选属性用decodeIfPresent
        
        // 2. 解析父类的属性（必须在子类属性初始化后调用）
        try super.init(from: decoder)
    }
    
    // 编码逻辑：先编码父类属性，再编码子类属性
    override func encode(to encoder: Encoder) throws {
        // 1. 编码父类的属性
        try super.encode(to: encoder)
        
        // 2. 编码子类自己的属性
        var subclassContainer = encoder.container(keyedBy: CodingKeys.self)
//        try subclassContainer.encode(school1, forKey: .school1)
        try subclassContainer.encodeIfPresent(grade, forKey: .grade)  // 可选属性用encodeIfPresent
    }
}

// 使用示例
func testCodableInheritance() {
    // 创建子类实例
    let student = Student(
        name: "Lily",
        age: 17,
        email: "lily@school.com",
        grade: 11
    )
    
    // 编码（对象转JSON）
    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    guard let jsonData = try? encoder.encode(student),
          let jsonString = String(data: jsonData, encoding: .utf8) else {
        print("编码失败")
        return
    }
    print("编码结果：\n\(jsonString)")
    // 输出包含父类和子类的所有属性：
    // {
    //   "name" : "Lily",
    //   "age" : 17,
    //   "email" : "lily@school.com",
    //   "school" : "Star High",
    //   "grade" : 11
    // }
    
    // 解码（JSON转对象）
    let decoder = JSONDecoder()
    guard let decodedStudent = try? decoder.decode(Student.self, from: jsonData) else {
        print("解码失败")
        return
    }
    print("\n解码结果：")
    print("姓名：\(decodedStudent.name)，年龄：\(decodedStudent.age)")
    print("学校：\(decodedStudent.school)，年级：\(decodedStudent.grade ?? 0)")
    // 输出：
    // 姓名：Lily，年龄：17
    // 学校：Star High，年级：11
}

// 执行测试
testCodableInheritance()

